灰度发布、蓝绿发布、金丝雀发布等,本质上没有区别,都是版本渐进式发布+流量管理,所以也不要去纠结自己的发布方式到底算哪一种。硬要说,灰度发布是渐进式发布的统称,蓝绿发布和金丝雀发布是渐进式发布的具体方式,详细区别,在于蓝绿发布强调蓝绿环境(即新版和旧版服务)的平等性,流量拆分粒度较粗;金丝雀发布拥有更细粒度的流量拆分。

原理分析

灰度发布两个核心点:流量管理、发布流程管理。先来分析流量管理,不算Istio等组件新引入的流量管理策略,仅以Kubernetes本身的组件来看。一个常见的后端服务具有如下网络拓扑结构:ingress作为流量入口、转发到Service、Service转发到Deployment下辖的RS管理的Pod(严格来说,Service背后就直接是Pod了,但此处为方便说明控制关系,将Deployment和RS也加入了其中)。

image-20220602103656153

这个结构有三种拆分流量的方式:按Service拆、按Deployment拆、按RS拆,如下

image-20220602104135230

下面依次说明如何进行管理

  • 按Service拆

    1. 发布新应用的Deployment、Service资源
    2. 利用Nginx Ingress Controller的nginx.ingress.kubernetes.io/canary系列注解或nginx.ingress.kubernetes.io/service-match系列注解控制流量在新旧Service之间的分配
    3. 测试新服务
    4. 修改流量分配,将流量全都导入新服务,关闭旧服务

    这种方式能够在七层进行流量控制,粒度可以任意细

  • 按Deployment拆

    1. 发布新应用的Deployment,将标签修改得符合原有Service的匹配规则,这样原Service就有两个应用
    2. 由于无法在七层精确控制流量打到新应用,因此只能观察新应用的监控表现是否正常
    3. 删除旧应用

    这种方式依赖的特性是Service的负载均衡,新应用分得的流量是pod的占比数,不适合精细控制的场合

  • 按RS拆

    这种方式无法在用户层使用,需要为Deployment编写新的控制器,控制新版本发布时RS切换流程,由原来的自动滚动发布变更为可手动控制的手动滚动发布,得到的效果和按Deployment拆分一致,但不需要用户再去创建和删除Deployment资源,一切滚动都自动化。argo rollout的默认做法就是这样

argo rollout

了解了灰度原理,但在实现上还是需要我们手动增删资源、发布后测试,argo rollout将这一切实现了自动化。主要功能如下

  • 灰度流程自动化,命令行控制灰度的进度
  • 支持多种流量管理方式,包括服务网格等
  • 提供自动化分析能力。可根据prometheus、普通http接口、Job执行结果情况控制灰度进度,实现完全的自动化

argo rollout也不是没有缺点:学习成本高、流量管理方式固定、和gitops兼容不好等。尤其是流量管理方式,如果网络拓扑结构不在其支持方式内,就无法使用,这也是下文没有使用它的原因。

灰度实践

我们的需求:应用灰度上线(不引入正式流量) - 执行冒烟测试 - 通过则正式上线,否则灰度下线。

而我们的网络结构如下,只有网关服务存在网络入口,其它应用只有Service,因此无法应用上述流量管理方式中的任何一种。

image-20220602111856505

对此,在网关服务做灰度流量管理更合适

image-20220602112021070

进一步,一般的灰度发布,在发布完成后都会将灰度应用转正,删除原有应用相关资源,但在我们的情况下,这样做有两点不方便之处

  • 网关服务的路由映射是单独写在配置文件的,且网关后面有多个应用,至关重要,不能经常去改,容易出错
  • gitops上难以实现

于是我们选择如下方式

  • 建立灰度发布环境

    • gitops中建立灰度应用的yaml清单文件,与原本的应用拥有资源一致,唯一的区别是名称多了个-canary
    • 网关路由配置中配置指向灰度应用的路由规则
  • 灰度发布

    • CI触发gitops更新灰度应用的yaml文件,更新副本数为1,更新灰度应用的镜像版本,等待灰度应用发布生效
    • 根据网关的路由配置,通过合适的方式访问灰度应用进行测试(比如添加指定请求头)
    • CI手动触发gitops更新正式应用的yaml文件,更新镜像版本,同时更新灰度应用的yaml文件,更新副本数为0(这是为了节省资源)
    • 至此,灰度发布完成

更新gitops相关文件,k8s资源自动随着更新

涉及到大量清单配置文件,过长,这里就不贴了

总结 - 如何选择灰度方案

需求不同,灰度方案也不同,能用到的工具也会不同。比如上面我们的网络拓扑结构决定了很难使用argo rollout这种现成的工具;比如需要七层的流量管理就不能使用只能在四层做流量划分的方案;如果对流量管理有更个性化的要求,流量划分还得自己来做,整个方案又有所不同。

抓住两个关键点,就能灵活选择适合自己的灰度方案。

留言

2022-06-01

⬆︎TOP